package in.co.codedoc.cg;

import in.co.codedoc.cg.velocity.VelocityAdapter;

import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.RoundCompleteEvent;
import com.sun.mirror.apt.RoundCompleteListener;

public class CGAnnotationProcessor implements AnnotationProcessor
{
	public CGAnnotationProcessor(AnnotationProcessorEnvironment env)
	{
		this.env = env;
	}
	
	private String[] getTemplates()
	{
		return getOptionArgument("-Atemplates=").split(",");
	}
	
	private String getTemplatesDir()
	{
		return getOptionArgument("-AtemplatesDir=");
	}

	private String getModuleLogCategory()
	{
		return getOptionArgument("-AmoduleLogCategory=");
	}
	
	private String getOptionArgument(String optionPrefix)
	{
		for (String key : env.getOptions().keySet())
		{
			if(key.startsWith(optionPrefix))
			{
				return key.substring(optionPrefix.length());
			}
		}
		
		return "";
	}
	
	public void process()
	{
		try
		{
			setProcessor();
			
			env.addListener
			(
				new RoundCompleteListener()
				{
					@Override
					public void roundComplete(RoundCompleteEvent evt)
					{
						roundNumber.set(roundNumber.get()+1);
					}
				}
			);

			new VelocityAdapter(getTemplatesDir(),getModuleLogCategory(),getTemplates()).execute();
		}
		finally
		{
			resetProcessor();
		}
	}
	
	public static int getRoundNumber()
	{
		return roundNumber.get();
	}
	
	public static CGAnnotationProcessor getProcessor()
	{
		return processor.get();
	}
	
	public AnnotationProcessorEnvironment getEnv()
	{
		return env;
	}
	
	private void setProcessor()
	{
		processor.set(this);
	}
	
	private void resetProcessor()
	{
		processor.set(null);
	}
	
	private AnnotationProcessorEnvironment env;
	private static ThreadLocal<CGAnnotationProcessor> processor = new ThreadLocal<CGAnnotationProcessor>();
	private static ThreadLocal<Integer> roundNumber = new ThreadLocal<Integer>()
														{
															{
																set(1);
															}
														};
}

